home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows (5th Edition) / Programming Windows, 5th ed. - Companion CD (097-0002183)(1999).iso / Chap08 / Clock / Clock.c next >
Encoding:
C/C++ Source or Header  |  1998-10-09  |  5.5 KB  |  190 lines

  1. /*--------------------------------------
  2.    CLOCK.C -- Analog Clock Program
  3.               (c) Charles Petzold, 1998
  4.   --------------------------------------*/
  5.  
  6. #include <windows.h>
  7. #include <math.h>
  8.  
  9. #define ID_TIMER    1
  10. #define TWOPI       (2 * 3.14159)
  11.  
  12. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
  13.  
  14. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  15.                     PSTR szCmdLine, int iCmdShow)
  16. {
  17.      static TCHAR szAppName[] = TEXT ("Clock") ;
  18.      HWND         hwnd;
  19.      MSG          msg;
  20.      WNDCLASS     wndclass ;
  21.      
  22.      wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  23.      wndclass.lpfnWndProc   = WndProc ;
  24.      wndclass.cbClsExtra    = 0 ;
  25.      wndclass.cbWndExtra    = 0 ;
  26.      wndclass.hInstance     = hInstance ;
  27.      wndclass.hIcon         = NULL ;
  28.      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  29.      wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  30.      wndclass.lpszMenuName  = NULL ;
  31.      wndclass.lpszClassName = szAppName ;
  32.      
  33.      if (!RegisterClass (&wndclass))
  34.      {
  35.           MessageBox (NULL, TEXT ("Program requires Windows NT!"), 
  36.                       szAppName, MB_ICONERROR) ;
  37.           return 0 ;
  38.      }
  39.      
  40.      hwnd = CreateWindow (szAppName, TEXT ("Analog Clock"),
  41.                           WS_OVERLAPPEDWINDOW,
  42.                           CW_USEDEFAULT, CW_USEDEFAULT,
  43.                           CW_USEDEFAULT, CW_USEDEFAULT,
  44.                           NULL, NULL, hInstance, NULL) ;
  45.      
  46.      ShowWindow (hwnd, iCmdShow) ;
  47.      UpdateWindow (hwnd) ;
  48.      
  49.      while (GetMessage (&msg, NULL, 0, 0))
  50.      {
  51.           TranslateMessage (&msg) ;
  52.           DispatchMessage (&msg) ;
  53.      }
  54.      return msg.wParam ;
  55. }
  56.  
  57. void SetIsotropic (HDC hdc, int cxClient, int cyClient)
  58. {
  59.      SetMapMode (hdc, MM_ISOTROPIC) ;
  60.      SetWindowExtEx (hdc, 1000, 1000, NULL) ;
  61.      SetViewportExtEx (hdc, cxClient / 2, -cyClient / 2, NULL) ;
  62.      SetViewportOrgEx (hdc, cxClient / 2,  cyClient / 2, NULL) ;
  63. }
  64.  
  65. void RotatePoint (POINT pt[], int iNum, int iAngle)
  66. {
  67.      int   i ;
  68.      POINT ptTemp ;
  69.      
  70.      for (i = 0 ; i < iNum ; i++)
  71.      {
  72.           ptTemp.x = (int) (pt[i].x * cos (TWOPI * iAngle / 360) +
  73.                pt[i].y * sin (TWOPI * iAngle / 360)) ;
  74.           
  75.           ptTemp.y = (int) (pt[i].y * cos (TWOPI * iAngle / 360) -
  76.                pt[i].x * sin (TWOPI * iAngle / 360)) ;
  77.           
  78.           pt[i] = ptTemp ;
  79.      }
  80. }
  81.  
  82. void DrawClock (HDC hdc)
  83. {
  84.      int   iAngle ;
  85.      POINT pt[3] ;
  86.      
  87.      for (iAngle = 0 ; iAngle < 360 ; iAngle += 6)
  88.      {
  89.           pt[0].x =   0 ;
  90.           pt[0].y = 900 ;
  91.           
  92.           RotatePoint (pt, 1, iAngle) ;
  93.           
  94.           pt[2].x = pt[2].y = iAngle % 5 ? 33 : 100 ;
  95.           
  96.           pt[0].x -= pt[2].x / 2 ;
  97.           pt[0].y -= pt[2].y / 2 ;
  98.           
  99.           pt[1].x  = pt[0].x + pt[2].x ;
  100.           pt[1].y  = pt[0].y + pt[2].y ;
  101.           
  102.           SelectObject (hdc, GetStockObject (BLACK_BRUSH)) ;
  103.           
  104.           Ellipse (hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y) ;
  105.      }
  106. }
  107.  
  108. void DrawHands (HDC hdc, SYSTEMTIME * pst, BOOL fChange)
  109. {
  110.      static POINT pt[3][5] = { 0, -150, 100, 0, 0, 600, -100, 0, 0, -150,
  111.                                0, -200,  50, 0, 0, 800,  -50, 0, 0, -200,
  112.                                0,    0,   0, 0, 0,   0,    0, 0, 0,  800 } ;
  113.      int          i, iAngle[3] ;
  114.      POINT        ptTemp[3][5] ;
  115.      
  116.      iAngle[0] = (pst->wHour * 30) % 360 + pst->wMinute / 2 ;
  117.      iAngle[1] =  pst->wMinute  *  6 ;
  118.      iAngle[2] =  pst->wSecond  *  6 ;
  119.      
  120.      memcpy (ptTemp, pt, sizeof (pt)) ;
  121.      
  122.      for (i = fChange ? 0 : 2 ; i < 3 ; i++)
  123.      {
  124.           RotatePoint (ptTemp[i], 5, iAngle[i]) ;
  125.           
  126.           Polyline (hdc, ptTemp[i], 5) ;
  127.      }
  128. }
  129.  
  130. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  131. {
  132.      static int        cxClient, cyClient ;
  133.      static SYSTEMTIME stPrevious ;
  134.      BOOL              fChange ;
  135.      HDC               hdc ;
  136.      PAINTSTRUCT       ps ;
  137.      SYSTEMTIME        st ;
  138.           
  139.      switch (message)
  140.      {
  141.      case WM_CREATE :
  142.           SetTimer (hwnd, ID_TIMER, 1000, NULL) ;
  143.           GetLocalTime (&st) ;
  144.           stPrevious = st ;
  145.           return 0 ;
  146.           
  147.      case WM_SIZE :
  148.           cxClient = LOWORD (lParam) ;
  149.           cyClient = HIWORD (lParam) ;
  150.           return 0 ;
  151.           
  152.      case WM_TIMER :
  153.           GetLocalTime (&st) ;
  154.                     
  155.           fChange = st.wHour   != stPrevious.wHour ||
  156.                     st.wMinute != stPrevious.wMinute ;
  157.           
  158.           hdc = GetDC (hwnd) ;
  159.           
  160.           SetIsotropic (hdc, cxClient, cyClient) ;
  161.           
  162.           SelectObject (hdc, GetStockObject (WHITE_PEN)) ;
  163.           DrawHands (hdc, &stPrevious, fChange) ;
  164.           
  165.           SelectObject (hdc, GetStockObject (BLACK_PEN)) ;
  166.           DrawHands (hdc, &st, TRUE) ;
  167.           
  168.           ReleaseDC (hwnd, hdc) ;
  169.           
  170.           stPrevious = st ;
  171.           return 0 ;
  172.           
  173.      case WM_PAINT :
  174.           hdc = BeginPaint (hwnd, &ps) ;
  175.           
  176.           SetIsotropic (hdc, cxClient, cyClient) ;
  177.           DrawClock    (hdc) ;
  178.           DrawHands    (hdc, &stPrevious, TRUE) ;
  179.           
  180.           EndPaint (hwnd, &ps) ;
  181.           return 0 ;
  182.           
  183.      case WM_DESTROY :
  184.           KillTimer (hwnd, ID_TIMER) ;
  185.           PostQuitMessage (0) ;
  186.           return 0 ;
  187.      }
  188.      return DefWindowProc (hwnd, message, wParam, lParam) ;
  189. }
  190.